﻿using System.Net.Sockets;
using System.Net;
using System;
public class ChattingServer
{
    public static Socket socket;
    public static List<ClinetInfo> clients = new List<ClinetInfo>();
    public static int bufferCount = 0;
    public class ClinetInfo
    {
        public Socket socket;
        public byte[] buffer = new byte[1024];
        public ClinetInfo(Socket socket)
        {
            this.socket = socket;
        }
    }

    public static void Main(string[] argv)
    {
        try
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(IPAddress.Any, 10001));
            socket.Listen(0);
            System.Threading.Thread.Sleep(15000);
            socket.BeginAccept(AcceptCallback, socket);
            Console.ReadLine();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    public static void AcceptCallback(IAsyncResult result)
    {
        try
        {
            Socket socket = (Socket)result.AsyncState;
            Socket client = socket.EndAccept(result);
            ClinetInfo info = new ClinetInfo(client);
            clients.Add(info);
            client.BeginReceive(info.buffer, bufferCount, 1024 - bufferCount, 0, ReceiveCallback, info);
            socket.BeginAccept(AcceptCallback, socket);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    public static void ReceiveCallback(IAsyncResult result)
    {
        try
        {
            ClinetInfo info = (ClinetInfo)result.AsyncState;
            int count = info.socket.EndReceive(result);
            bufferCount += count;
            DealReceiveData(info);


            info.socket.BeginReceive(info.buffer, bufferCount, 1024 - bufferCount, 0, ReceiveCallback, info);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    public static void DealReceiveData(ClinetInfo info)
    {
        if (bufferCount <= 2)
            return;
        Int16 len = BitConverter.ToInt16(info.buffer, 0);
        if (bufferCount < 2 + len)
            return;

        foreach (var c in clients)
            c.socket.Send(info.buffer, 0, 2 + len, 0);

        int start = 2 + len;
        int count = bufferCount - start;
        Array.Copy(info.buffer, start, info.buffer, 0, count);
        bufferCount -= start;
        DealReceiveData(info);
    }
}